package com.lznAdmin.security.config;

import com.lznAdmin.properties.SecurityProperties;
import com.lznAdmin.security.authentication.code.ImageCodeValidateFilter;
import com.lznAdmin.security.authorize.AuthorizeConfigurerManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.sql.DataSource;

@Configuration
@EnableWebSecurity // 开启springsecurity过滤链
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    // 记住我功能
    @Autowired
    DataSource dataSource;
    @Autowired
    ImageCodeValidateFilter imageCodeValidateFilter;
    @Autowired
    private CustomAuthenticationFailHandler customAuthenticationFailHandler;
    @Autowired
    private CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
    @Autowired
    private SecurityProperties securityProperties;
    @Autowired
    private UserDetailsService customUserDetailsService;
    @Autowired
    private AuthorizeConfigurerManager authorizeConfigurerManager;
    @Autowired
    private CustomLogoutSuccessHandler customLogoutSuccessHandler;
    @Autowired
    private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
    /**
     * 允许匿名访问的url
     */
    private static final String[] URL_WHITELIST = {
            "/login",
            "/logout",
            "/code/image",
            "/favicon.ico",
            "/swagger-ui.html",
            "/swagger-resources/**",
            "/v2/**",
            "/webjars/**"
    };
    @Autowired
    private JwtAccessDeniedHandler jwtAccessDeniedHandler;

    @Bean
    JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {
        return new JwtAuthenticationFilter(authenticationManager());
    }

    /**
     * @Description: 身份认证管理器
     * 1.认证信息（用户名，密码）
     * @Param: [auth]
     * @Author: lzn
     * @Date: 2021/7/21
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService);
    }

    /**
     * @Description: 资源权限配置：
     * 1.被拦截的资源
     * @Param: [http]
     * @Author: lzn
     * @Date: 2021/7/21
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // http相关的配置，包括登入登出、异常处理、会话管理等
        http.cors().and().csrf().disable()

                // 登录配置
                .formLogin()
                .successHandler(customAuthenticationSuccessHandler)
                .failureHandler(customAuthenticationFailHandler)

                .and()
                .logout()
                .logoutSuccessHandler(customLogoutSuccessHandler)

                // 禁用session
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)

                // 配置拦截规则
                .and()
                .authorizeRequests()
                .antMatchers(URL_WHITELIST).permitAll()
                .anyRequest().authenticated()

                // 异常处理器
                .and()
                .exceptionHandling()
                .authenticationEntryPoint(jwtAuthenticationEntryPoint)
                .accessDeniedHandler(jwtAccessDeniedHandler)

                // 配置自定义的过滤器
                .and()
                .addFilter(jwtAuthenticationFilter())
                .addFilterBefore(imageCodeValidateFilter, UsernamePasswordAuthenticationFilter.class);

        // 权限相关配置管理者, 将所有授权配置管理起来了
        // authorizeConfigurerManager.configure(http.authorizeRequests());
    }

    // @Override
    // protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    //     auth.userDetailsService(userDetailService);
    // }
    // @Override
    // public void configure(WebSecurity web) throws Exception {
    //     // 配置不拦截的静态资源
    //     web.ignoring().antMatchers(securityProperties.getAuthentication().getStaticPaths());
    // }
}
